package com.futvan.z.framework.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Arrays;

import org.apache.commons.codec.binary.Base64;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.binary.Hex;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import com.futvan.z.framework.core.z;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

public class StringUtil {
	


	/**
	 * 判读是否包含汉字
	 * @param str
	 * @return
	 */
	public static boolean hasChinese(String str) {
		boolean r = false;
		if(z.isNotNull(str)) {
			char[] ch = str.toCharArray();
			for (char c : ch) {
				if (isChinese(c)) {
					return true;// 有一个中文字符就返回
				}
			}
		}
		return r;
	}
	private static boolean isChinese(char c) {
		Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
		if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS) {
			return true;
		} else if (ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS) {
			return true;
		} else if (ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION) {
			return true;
		} else if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A) {
			return true;
		} else if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B) {
			return true;
		} else if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C) {
			return true;
		} else if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D) {
			return true;
		} else if (ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
			return true;
		} else if (ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
			return true;
		}
		return false;
	}

	public static String print(Object obj) {
		if(z.isNotNull(obj)) {
			return String.valueOf(obj);
		}else {
			return "";
		}
	}

	/**
	 * URL特殊字符转义
	 * @param str
	 * @return
	 */
	public static String UrlEncode(String str) {
		String result = "";
		if(z.isNotNull(str)) {
			try {
				result = URLEncoder.encode(str, "utf-8");
			} catch (Exception e) {
				z.Error("UrlEncode Error", e);
			}
		}
		return result;
	}

	/**
	 * URL特殊字符转义还原
	 * @param str
	 * @return
	 */
	public static String UrlDecode(String str) {
		String result = "";
		if(z.isNotNull(str)) {
			try {
				result = URLDecoder.decode(str, "utf-8");
			} catch (Exception e) {
				z.Error("UrlDecode Error", e);
			}
		}
		return result;
	}

	/**
	 * 判读字符串是否可以转换成BigDecimal
	 * @param str
	 * @return
	 */
	public static boolean isBigDecimal(String str) {
		BigDecimal tmp = null;
		try {
			tmp = new BigDecimal(str);
		} catch (Exception e) {
			tmp = null;
		}
		if(tmp!=null) {
			return true;
		}else {
			return false;
		}
	}
	
	/**
	 * 转意SQL中的特殊字符
	 * @param sql
	 * @return
	 */
	public static String conversionSQL(String sql) {
		if(z.isNotNull(sql)) {
			//{}
			sql = sql.replaceAll("\\{", "\\\\{").replaceAll("\\}", "\\\\}");
			//'
			sql = sql.replaceAll("\\'", "\\\\'");
		}
		return sql;	
	}

	/**
	 * 解析表达式-替换变量
	 * @param str 变量表示方法   #{#cmsid}
	 * 
	 * 
	 * 			常用系统变量： newnumber 生成一个编号【唯一】
	 * 					   newdate 获取系统日期yyyy-MM-dd
	 * 					   newdatetime 获取系统日期时间yyyy-MM-dd HH:mm:ss
	 *                     
	 * @return
	 * 
	 * 例：	String test = "SELECT * FROM cms_info where zid = '#{#cmsid}'";
			HashMap<String,String> sp = new HashMap<String,String>();
			sp.put("cmsid", "cccccccccccccccccc");
			String sql = parseExpression(test, sp);
			System.out.println(sql);
	 */
	public static String parseExpression(String expression,Map<String,String> sp){
		String new_sql = "";
		if(z.isNotNull(expression)) {
			//创建SQL解析对象
			ExpressionParser ep = new SpelExpressionParser();

			//获取变量值，并封闭成EvaluationContext上下文变量
			EvaluationContext ctx = new StandardEvaluationContext();
			if(z.isNotNull(sp)) {
				for (Map.Entry<String,String> entry : sp.entrySet()) {
					ctx.setVariable(entry.getKey(), entry.getValue());
				}
				//添加系统变量值
				ctx.setVariable("newnumber", z.newNumber());
				ctx.setVariable("newdate", DateUtil.getDate());
				ctx.setVariable("newdatetime", DateUtil.getDateTime());
			}
			//变量替换
			new_sql = String.valueOf(ep.parseExpression(expression, new TemplateParserContext()).getValue(ctx));
		}
		return new_sql;
	}



	/**
	 * 判读是否为空
	 * @param obj
	 * @return
	 */
	public static String toString(Object obj) {
		if(z.isNull(obj)) {
			return "";
		}else {
			return String.valueOf(obj);
		}
	}

	
	/**
	 * 加密方法(可逆加密)
	 * 
	 * @param str
	 * @return
	 */
	public static String jia_old(String str) {
		String returnvalue = "";
		char[] s1 = str.toCharArray();
		String sb1 = "";
		for (int i = s1.length - 1; i >= 0; i--) {
			int srtchar = s1[i] + 3;// 加3
			sb1 = sb1 + (char) srtchar;
		}
		returnvalue = sb1;
		return returnvalue;
	}

	/**
	 * 解密方法
	 * 
	 * @param str
	 * @return
	 */
	public static String jie_old(String str) {
		String returnvalue = "";
		char[] s1 = str.toCharArray();
		String sb1 = "";
		for (int i = s1.length - 1; i >= 0; i--) {
			int srtchar = s1[i] - 3;// 减3
			sb1 = sb1 + (char) srtchar;
		}
		returnvalue = sb1;
		return returnvalue;
	}
	
	public static void main(String[] args) {
		String j = jia_old("D:☆zz☆eclipse☆workspace☆zj☆.metadata☆.plugins☆org.eclipse.wst.server.core☆tmp0☆wtpwebapps☆zf☆files☆73fbbf0508654ad2b69e4a8d306f0325☆asdf.jpg");
		System.out.println(j);
		
		System.out.println(jie_old(j));
	
		
	}
	/**
	 * 	字符串加密
	 * @param str
	 * @return
	 */
	public static String jia(String str) {
		String result = "";
		try {
			if(str.indexOf("☆")<0) {
				throw new Exception("error jia");
			}
			String tableId = str.substring(str.lastIndexOf("☆")+1);
			String zid = str.substring(0,str.lastIndexOf("☆"));
			StringBuilder strsb = new StringBuilder(zid);

			for (int i = 0; i < tableId.length(); i++) {
				//获取加密串的每一个字节
				String t = tableId.substring(i, i+1);
				int offset = MathUtil.getRandom(10, 30);
				strsb.insert(offset, t);
				strsb.append(offset);
			}

			if(tableId.length()>=10) {
				strsb.append(tableId.length());
			}else {
				strsb.append("0"+tableId.length());
			}
			result = strsb.toString().replace("_", "12517");
		} catch (Exception e) {
			result = str;
		}
		return result;
	}

	
	/**
	 * 	字符串解密
	 * @param str
	 * @return
	 */
	public static String jie(String str) {
		String result = "";
		try {
			str = str.replace("12517", "_");
			int tableIdLength = new Integer(str.substring(str.length()-2));
			str = str.substring(0, str.length()-2);
			String tableIdoffset = str.substring(str.length()-tableIdLength*2);
			str = str.replace(tableIdoffset, "");

			List<String> strarray = new LinkedList<String>();
			for (int i = 0; i < str.length(); i++) {
				strarray.add(str.substring(i, i+1));
			}

			String tableid = "";
			for (int i = tableIdLength; i>0; i--) {
				int toffset = new Integer(tableIdoffset.substring(i*2-2, i*2));
				String t = strarray.get(toffset);
				tableid = t+tableid;
				strarray.remove(toffset);
			}
			result = getListToString(strarray)+"☆"+tableid;
		} catch (Exception e) {
			result = str;
		}
		return result;
	}

	private static String getListToString(List<String> list) {
		String reslut = "";
		for (String str : list) {
			reslut = reslut+str;
		}
		return reslut;
	}

	/**
	 * 字符串模糊处理
	 * 
	 * @param txt
	 * @return
	 */
	public static String blurred(String txt) {
		StringBuffer returnvalue = new StringBuffer();
		if (!"".equals(txt) && txt != null) {
			// 默认将字符1/3中间位置字符串变为*号
			for (int i = 0; i < txt.length(); i++) {
				if (i < txt.length() / 3 || i > txt.length() / 3 * 2) {
					returnvalue.append(txt.substring(i, i + 1));
				} else {
					returnvalue.append("*");
				}
			}
		}
		return returnvalue.toString();
	}

	/**
	 * 首字母变大写
	 * 
	 * @param str
	 * @return
	 */
	public static String firstLetterToUpper(String str) {
		String returnvalue = null;
		char[] array = str.toCharArray();
		if (Character.isUpperCase(array[0])) {
			returnvalue = String.valueOf(array);
		} else {
			array[0] -= 32;
			returnvalue = String.valueOf(array);
		}
		return returnvalue;
	}

	/**
	 * 首字母变小写
	 * 
	 * @param str
	 * @return
	 */
	public static String firstLetterToLower(String str) {
		String returnvalue = null;
		char[] array = str.toCharArray();
		if (Character.isLowerCase(array[0])) {
			returnvalue = String.valueOf(array);
		} else {
			array[0] += 32;
			returnvalue = String.valueOf(array);
		}
		return returnvalue;
	}

	/**
	 * 列转行
	 * 
	 * @param list
	 *            数据集合
	 * @param delimiter
	 *            分隔符 例：","
	 * @param bracketsLeft
	 *            左括号符号
	 * @param bracketsRight
	 *            右括号符号
	 * @return String
	 */
	public static String ListToString(List<String> list, String delimiter,
			String bracketsLeft, String bracketsRight) {
		String returnvalue = "";
		for (String string : list) {
			if (bracketsLeft != null && bracketsRight != null) {
				returnvalue += bracketsLeft + string + bracketsRight;
			} else {
				returnvalue += string;
			}
			returnvalue += delimiter;
		}
		if ("".equals(returnvalue) || returnvalue == null) {
			return returnvalue;
		} else {
			return returnvalue.substring(0, returnvalue.length() - 1);
		}
	}

	/**
	 * 列转行
	 * 
	 * @param list
	 *            数据集合
	 * @param delimiter
	 *            分隔符 例：","
	 * @param bracketsLeft
	 *            左括号符号
	 * @param bracketsRight
	 *            右括号符号
	 * @return String
	 */
	public static String ListToString(String[] list, String delimiter,String bracketsLeft, String bracketsRight) {
		return ListToString(Arrays.asList(list), delimiter, bracketsLeft, bracketsRight);
	}

	/**
	 * 列转行
	 * 
	 * @param list
	 *            数据集合
	 * @param delimiter
	 *            分隔符 例：","
	 * @param bracketsLeft
	 *            左括号符号
	 * @param bracketsRight
	 *            右括号符号
	 * @return String
	 */
	public static String ListToString(String stringlist, String delimiter,String bracketsLeft, String bracketsRight) {
		return ListToString(stringlist.split(","), delimiter, bracketsLeft, bracketsRight);
	}
	
	/**
	 * 字符串自动转成SQL in 语句条件
	 * @param ids
	 * @return
	 */
	public static String ListToSqlInArray(String ids) {
		String result = "";
		if(z.isNotNull(ids)) {
			String[] idarray = ids.split(",");
			result = ListToString(Arrays.asList(idarray), ",", "'", "'");
		}
		return result;
	}

	/**
	 * 获取汉字串拼音首字母，英文字符不变
	 * 
	 * @param chinese
	 *            汉字串
	 * @return 汉语拼音首字母
	 */
	public static String getFirstSpell(String chinese) {
		StringBuffer pybf = new StringBuffer();
		char[] arr = chinese.toCharArray();
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		for (int i = 0; i < arr.length; i++) {
			if (arr[i] > 128) {
				try {
					String[] temp = PinyinHelper.toHanyuPinyinStringArray(
							arr[i], defaultFormat);
					if (temp != null) {
						pybf.append(temp[0].charAt(0));
					}
				} catch (BadHanyuPinyinOutputFormatCombination e) {
					e.printStackTrace();
				}
			} else {
				pybf.append(arr[i]);
			}
		}
		return pybf.toString().replaceAll("\\W", "").trim();
	}

	/**  
	 * 获取汉字串拼音，英文字符不变  
	 * @param chinese 汉字串  
	 * @return 汉语拼音  
	 */   
	public static String getFullSpell(String chinese) {   
		StringBuffer pybf = new StringBuffer();   
		char[] arr = chinese.toCharArray();   
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();   
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);   
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);   
		for (int i = 0; i < arr.length; i++) {   
			if (arr[i] > 128) {   
				try {   
					pybf.append(PinyinHelper.toHanyuPinyinStringArray(arr[i], defaultFormat)[0]);   
				} catch (BadHanyuPinyinOutputFormatCombination e) {   
					e.printStackTrace();   
				}   
			} else {   
				pybf.append(arr[i]);   
			}   
		}   
		return pybf.toString();   
	}  


	/**
	 * 加密方法(不可逆加密)
	 * 
	 * @param str
	 *            标示信息
	 * @return License码
	 * @throws Exception
	 */
	public static String CreatePassword(String str) {
		String infoMd5 = toMD5(str);
		StringBuffer LicenseInfo = new StringBuffer();
		LicenseInfo.append(toMD5(infoMd5.substring(0, 8)));
		LicenseInfo.append(toMD5(infoMd5.substring(8, 16)));
		LicenseInfo.append(toMD5(infoMd5.substring(16, 24)));
		LicenseInfo.append(toMD5(infoMd5.substring(24, 32)));
		return toMD5(LicenseInfo.toString());
	}

	/**
	 * MD5加密类
	 * 
	 * @param str
	 *            要加密的字符串
	 * @return 加密后的字符串
	 * @throws Exception
	 */
	public static String toMD5(String str) {
		StringBuffer buf = new StringBuffer("");
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(str.getBytes());
			byte[] byteDigest = md.digest();
			int i;
			for (int offset = 0; offset < byteDigest.length; offset++) {
				i = byteDigest[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		// 32位加密
		return buf.toString();
	}

	/**
    * 利用java原生的类实现SHA256加密
    * @param str 加密后的报文
    * @return
    */
	public static String toSHA256(String str){
		MessageDigest messageDigest;
		String encodestr = "";
		try {
			messageDigest = MessageDigest.getInstance("SHA-256");
			messageDigest.update(str.getBytes("UTF-8"));
			encodestr = byte2Hex(messageDigest.digest());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return encodestr;
	}

	/**
    * 将byte转为16进制
    * @param bytes
    * @return
    */
	public static String byte2Hex(byte[] bytes){
		StringBuffer stringBuffer = new StringBuffer();
		String temp = null;
		for (int i=0;i<bytes.length;i++){
			temp = Integer.toHexString(bytes[i] & 0xFF);
			if (temp.length()==1){
				//1得到一位的进行补0操作
				stringBuffer.append("0");
			}
			stringBuffer.append(temp);
		}
		return stringBuffer.toString();
	}

	/**
	 * 异常信息转字符串
	 * @param e 异常对象
	 * @return String
	 */
	public static String ExceptionToString(Exception e) {
		String result = "";
		if(e!=null && e instanceof Exception) {
			StringWriter sw = new StringWriter();  
			e.printStackTrace(new PrintWriter(sw, true));
			result = sw.toString();
		}
		return result;
	}
}
